﻿using System;
using System.Collections;
using AcademicPlanner.Data.Entities;
using NHibernate.Tool.hbm2ddl;
using NHibernate;

namespace AcademicPlanner.Data.Repositories
{
	/// <summary>
	/// PersonEntityRepository serves as the repository for <c>PersonEntity</c>s.
	/// </summary>
	/// <version>1.0</version>
	/// <since>1.0</since>
    public class PersonEntityRepository : EntityRepository<PersonEntity>
    {
		private PersonEntityRepository() 
		{ 
			namedQueriesPrefix = "PersonEntity";
		}

		private class InstanceHolder 
		{
			internal static PersonEntityRepository INSTANCE = new PersonEntityRepository(); 
		}


		/// <summary>
		/// The the single instance of PersonEntityRepository.
		/// </summary>
		/// <returns>The single instance of PersonEntityRepository.</returns>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public static PersonEntityRepository GetInstance()
		{ 
			return InstanceHolder.INSTANCE; 
		}


		/// <summary>
		/// Creates a new <c>PersonEntity</c> and sets its default values.
		/// </summary>
		/// <returns>The newly created <c>PersonEntity</c>.</returns>
		/// <seealso cref="M:AcademicPlanner.Data.Entities.PersonEntity.SetDefaults"/>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public PersonEntity GetNew()
		{
			var rEnt = new PersonEntity();
			rEnt.SetDefaults();
			return rEnt;
		}

		/// <summary>
		/// Finds the <c>PersonEntity</c> that has the given email address from
		/// the persistence layer.
		/// </summary>
		/// <param name="pEmail">The email address to find a macthing <c>PersonEntity</c> for.</param>
		/// <returns>The <c>PersonEntity</c> or <c>null</c>.</returns>
		/// <exception cref="T:AcademicPlanner.Data.DataException">
		/// Thrown with an error code of <c>DataErrorCode.QUERY_PERSON_ENTITY_BY_EMAIL_FAILED</c>
		/// when an error is reported by NHibernate. The <c>HibernateException</c> is
		/// accessible via the <c>InnerException</c> property.
		/// </exception>
		/// <version>1.0</version>
		/// <since>1.0</since>
		public PersonEntity FindByEmail(string pEmail)
		{
			PersonEntity rEnt = null;
			IQuery vQuery = GetQuery("by.email");
			IList vEnts;

			try
			{
				vQuery.SetString("email", pEmail);
				vQuery.SetMaxResults(1);
				vEnts = vQuery.List();
			}
			catch (HibernateException vHx)
			{
				var vDx = new DataException(DataErrorCode.QUERY_PERSON_ENTITY_BY_EMAIL_FAILED, vHx);
				throw vDx;
			}

			if (vEnts.Count > 0)
				rEnt = (PersonEntity)vEnts[0];

			return rEnt;
		}

		
    }
}
